home *** CD-ROM | disk | FTP | other *** search
- #
- # File: tcprpmd.pl
- # Author: G. Paul Ziemba
- # Date: 92.01.24
- # SCCS: @(#)tcprpmd.pl 1.10 4/23/93
- # Purpose: listen for relay session requests; set up tcprelay and
- # return port info to client. Called from inetd.
- #
-
- #########################
- # Begin Configuration #
- #########################
-
- $RelayProg = $EXEC_PATH . "/tcprelay";
- $VersionString = "1.10";
-
- #########################
- # End Configuration #
- #########################
-
- $myname = $0;
- $myname =~ s:^.*/::;
- if (($ARGV[0] eq "-d") || ($myname eq "tcprpmd-d")) {
- $debug = 1;
- }
-
- $R_OK = "250 OK\n";
-
- $| = 1; # see if this is really necessary
-
- chop($MyHostname = `hostname`);
- unless (do 'sys/socket.ph') {
- eval 'sub SOCK_STREAM {1;} sub AF_INET {2;} sub PF_INET {2;}';
- }
-
- #
- # Find out who conected to us
- #
- ($family, $port, $client_ip) = unpack('S n a4 x8', getpeername(STDIN));
- $client_name = gethostbyaddr($client_ip, &AF_INET);
-
- #
- # if name lookup failed, then just use dotted quad
- #
- if ($client_name eq "") {
- $client_name = join('.', unpack('C4', $client_ip));
- }
-
- #
- # Ready for action
- #
- print "220 $MyHostname tcpr-portmapper version $VersionString ready ".
- "client=[$client_name]\n";
-
- #
- # command interpreter
- #
- while (<STDIN>) {
- chop;
- ($_, $arg, $rest) = split(/\s+/);
- tr/A-Z/a-z/;
- if (/^server$/) {
- if (&badarg($arg)) {
- print "550 Invalid argument\n";
- next;
- }
- $Server = $arg;
- print "230-server[$Server]\n";
- print $R_OK;
- } elsif (/^mode$/) {
- if (&badarg($arg) || ($arg ne "ftp")) {
- print "550 Invalid argument\n";
- next;
- }
- $Mode = "-ftp";
- print "230-mode[$arg]\n";
- print $R_OK;
- } elsif (/^service$/) {
- if (&badarg($arg)) {
- print "550 Invalid argument\n";
- next;
- }
- $Service = $arg;
- print "230-service[$Service]\n";
- print $R_OK;
- } elsif (/^nop$/) {
- print $R_OK;
- } elsif (/^relay$/) {
- if (!defined($Server) || !defined($Service)) {
- print "503 Bad Command Sequence\n";
- }
- &relay($Server, $Service);
- } elsif (/^quit$/) {
- print "221 Closing connection\n";
- exit 0;
- } else {
- print "500 Syntax error\n";
- }
- }
- exit 1;
-
- #
- # verify server and service syntax
- #
- sub badarg {
- local($_) = $_[0];
-
- s/\s//g;
- if ($_ eq "") {
- return 1;
- }
- if (/[\!\@\#\$\%\^\&\*\(\)\{\}\[\]\:\;\"\'\~\`\<\>\,\?\/]/) {
- return 1;
- }
- return 0;
- }
-
- #
- # Call the relay program, capture the port number, and return it to client
- #
- sub relay {
- local($Server, $Service) = @_[0,1];
- local(@elist) = ($Server, $client_name, $Service);
-
- # avoid metacharacter cracker holes
- if (!open(RELAY, "-|")) {
- open(STDERR, ">&STDOUT");
- if ($debug) {
- unshift(@elist, "-d");
- }
- if (defined($Mode)) {
- unshift(@elist, $Mode);
- }
- exec $RelayProg, @elist;
- print "551 exec($RelayProg) failed: $!\n";
- exit 1;
- }
-
- while (<RELAY>) {
- #
- # lines from tcprelay starting with 9\d\d are error
- # messages to be forwarded to client
- #
- if (/^9\d\d\s+(\S.*)$/) {
- push(@errlist, $1);
- } else {
- push(@remarklist, $_);
- }
- next if (!/port=/);
-
- #
- # Success
- #
- s/^.*port=//;
- s/(\d+)\D+/\1/;
- print "212 PORT $_\n";
- ++$gotport;
- }
- close (RELAY);
-
- if ($gotport) {
- exit 0;
- }
- foreach (@remarklist) {
- print "230-$_";
- }
- foreach (@errlist) {
- print "550-$_";
- }
- print "550 relay failed\n";
-
- exit 1;
- }
-